package org.github.manx98.jlibhac.tools.fssystem.romfs;

import org.github.manx98.jlibhac.fs.fsa.DirectoryEntry;
import org.github.manx98.jlibhac.fs.fsa.DirectoryEntryType;
import org.github.manx98.jlibhac.fs.fsa.IDirectory;
import org.github.manx98.jlibhac.fs.fsa.OpenDirectoryMode;

import java.io.IOException;

/**
 * @author Manx98
 * @version 1.0
 * @since 2022/10/5 1:59
 */
public class RomFsDirectory extends IDirectory {
    private final RomFsFileSystem parentFileSystem;
    private final FindPosition initialPosition;
    private final FindPosition currentPosition;
    private final OpenDirectoryMode mode;

    public RomFsDirectory(RomFsFileSystem fs, FindPosition position, OpenDirectoryMode mode) {
        this.parentFileSystem = fs;
        this.initialPosition = new FindPosition(position.NextDirectory, position.NextFile);
        this.currentPosition = new FindPosition(position.NextDirectory, position.NextFile);
        this.mode = mode;
    }

    @Override
    public long doRead(DirectoryEntry[] entryBuffer) throws IOException {
        return readImpl(entryBuffer, currentPosition);
    }

    private long readImpl(DirectoryEntry[] entryBuffer, FindPosition position) throws IOException {
        HierarchicalRomFileTable tab = parentFileSystem.fileTable;

        int i = 0;

        if (mode.hasFlag(OpenDirectoryMode.Directory)) {
            String name;
            while ((entryBuffer.length == 0 || i < entryBuffer.length) && (name = tab.findNextDirectory(position)) != null) {
                if (entryBuffer.length > 0) {
                    DirectoryEntry entry = entryBuffer[i];
                    entry.Name = name;
                    entry.Type = DirectoryEntryType.Directory;
                    entry.Size = 0;
                }
                i++;
            }
        }
        if (mode.hasFlag(OpenDirectoryMode.File)) {
            while ((entryBuffer.length == 0 || i < entryBuffer.length)) {
                RomFsDictionary.EntryReferenceResult<FileRomEntry> nextFile = tab.findNextFile(position);
                if (nextFile == null) {
                    break;
                }
                if (entryBuffer.length != 0) {
                    DirectoryEntry entry = new DirectoryEntry();
                    entryBuffer[i] = entry;
                    entry.Name = nextFile.name;
                    entry.Type = DirectoryEntryType.File;
                    entry.Size = nextFile.entry.Value.Info.Length;
                }
                i++;
            }
        }
        return i;
    }

    @Override
    public long doGetEntryCount() {
        return 0;
    }
}
